package com.andy.qhb.schd;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.annotation.PreDestroy;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.andy.qhb.dao.DaoUtils;
import com.andy.qhb.dao.vo.Where;
import com.andy.qhb.entity.UsrDayRept;
import com.andy.qhb.entity.UsrUser;
import com.andy.qhb.game.GameConf;
import com.andy.qhb.game.GameUtils;
import com.andy.qhb.game.Global;
import com.andy.qhb.game.QhbGame;
import com.andy.qhb.game.RobotManager;
import com.andy.qhb.game.Room;
import com.andy.qhb.utils.DateUtil;
import com.andy.qhb.utils.GoConstant;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

@Component
public class BatchScheduler {

	private final Logger logger = LoggerFactory.getLogger(this.getClass()); 
	
	/**
	 * 返佣结算
	 */
	@Scheduled(cron="10 0 0 * * ?") //每天0点0分10s执行一次
//	@Scheduled(cron="0 * * * * ?")
	public void fanyongjiesuan() {
		logger.info("返佣结算，开始……");
		String day = DateUtil.dateFormat(DateUtil.addDay(new Date(), -1));
		long count = DaoUtils.count("select count(1) from usr_day_rept where day = ?", day);
		if(count > 0)return;
		try {
			doFanyongjiesuan(day);
		} catch (Exception e) {
			logger.error("返佣结算异常",e);
		}
		logger.info("返佣结算，结束！");
	}

	private void doFanyongjiesuan(String day) {
		
		Map<Integer, List<UsrUser>> levelMaps = Maps.newHashMap();
		Map<Long, Item> users = Maps.newHashMap();
		// 查询代理用户且不是机器人
		List<UsrUser> usersA = DaoUtils.getList(UsrUser.class,Where.gt("agent", 0),Where.gt("id", 200000));
		for(UsrUser user:usersA) {
			List<UsrUser> list = levelMaps.get(user.getAgent());
			if(list == null) {
				list = Lists.newArrayList();
				levelMaps.put(user.getAgent(), list);
			}
			list.add(user);
			users.put(user.getId(), new Item(user.getAgent(),user.getPuid()));
		}
		
		// 从第7级代理开始结算
		for(int i=7;i>0;i--) {
			List<UsrUser> levels = levelMaps.get(i);
			if(levels != null) {
				for(UsrUser user:levels) {
					doJiesuan(users,user,i);
				}
			}
		}
		
		// 入库
		List<UsrDayRept> entitys = Lists.newArrayList();
		for(Entry<Long, Item> entry:users.entrySet()) {
			UsrDayRept dayRept = new UsrDayRept();
			dayRept.setUid(entry.getKey());
			dayRept.setAllCoin(entry.getValue().coin);
			dayRept.setType(0);
			dayRept.setDay(day);
			dayRept.setStatus(1);
			
			entitys.add(dayRept);
			if(entitys.size() % 100 == 0) {
				DaoUtils.batchSave(entitys, false);
				entitys.clear();
			}
		}
		
		DaoUtils.batchSave(entitys, false);
		
	}
	
	private void doJiesuan(Map<Long, Item> users, UsrUser user, int agent) {
		Long endTime = DateUtil.getCurrentDateLong();
		Long startTime = endTime - 86400;
		// 路人局
		String sql = "select sum(q.coin) as total from usr_qiangb_log q,usr_fab_log g where q.pid=g.id "
				+ "and q.miansi = 1 and (q.create_time >= ? and q.create_time < ?) " 
				+ "and g.room_id >= 10000000 and g.uid in (select t.id from usr_user t where t.puid = ?)";
		
		Map total = DaoUtils.getOneSql(sql , startTime,endTime,user.getId());
		Long coin = MapUtils.getLong(total, "total");
		if(coin != null) {
			long mycoin = (8-agent)*10*coin/100;
			users.get(user.getId()).addCoin(mycoin);
			
			// 其他分给上级代理10%
			Long puid = user.getPuid();
			while(puid != null && puid > 0 && agent-- > 1) {
				users.get(puid).addCoin(10*coin/100);
				puid = users.get(puid).puid;
			}
		}
		
		// 私群
		sql = "select sum(q.coin) as total from usr_qiangb_log q,usr_fab_log g where q.pid=g.id "
				+ "and q.miansi = 1 and (q.create_time >= ? and q.create_time < ?) " 
				+ "and g.room_id < 10000000 and g.uid in (select t.id from usr_user t where t.puid = ?)";
		
		total = DaoUtils.getOneSql(sql , startTime,endTime,user.getId());
		coin = MapUtils.getLong(total, "total");
		
		if(coin != null) {
			// 私群抽5%
			long mycoin = 5*coin/100;
			users.get(user.getId()).addCoin(mycoin);
		}
		
	}

	private static class Item {
		
		public Item(Integer agent,Long puid){
			this.agent = agent;
			this.puid = puid;
		}
		
		public void addCoin(long mycoin) {
			this.coin += mycoin;
		}

		Long coin = 0L;
		Integer agent;
		Long puid;
	}
	
	private static QhbGame flGame = null;
	/**
	 * 福利群
	 */
	@Scheduled(cron="0 30 20 * * ?") //每天20点30分0s执行一次
//	@Scheduled(cron="0 * * * * ?")
	public void fafuli() {
		if(flGame != null) {
			flGame.end();
		}
		
		// 查询9点到晚上20:30发包超过2000的玩家
		Long startTime = DateUtil.getCurrentDateLong()+9*3600;
		Long endTime = startTime+11*3600+30*60;
		String sql = "select t.uid from usr_fab_log t where t.uid > 200000 and (t.create_time >= ? and t.create_time < ?)  " 
				+ " GROUP BY t.uid having sum(t.coin) >= 200000";
		List<Map<String, Object>> uids = DaoUtils.getListSql(sql, startTime,endTime);
		Set<Long> userids = Sets.newHashSet();
		uids.forEach((it)->{
			userids.add(MapUtils.getLong(it, "uid"));
		});
		Global.currFlUids = userids;
		int count = userids.size();
		if(count < 20) return;
		
		int index = 0;
		if(count >= 1000) {
			index = 12;
		}else if(count >= 900) {
			index = 11;
		}else if(count >= 800) {
			index = 10;
		}else if(count >= 700) {
			index = 9;
		}else if(count >= 600) {
			index = 8;
		}else if(count >= 500) {
			index = 7;
		}else if(count >= 400) {
			index = 6;
		}else if(count >= 300) {
			index = 5;
		}else if(count >= 200) {
			index = 4;
		}else if(count >= 150) {
			index = 3;
		}else if(count >= 100) {
			index = 2;
		}else if(count >= 50) {
			index = 1;
		}else if(count >= 20) {
			index = 0;
		}
		
		int coin = GameConf.fuliFabCoin[index]*100;
		Room room = Global.getRoom(GoConstant.LRROOM_ID_START*GoConstant.GAME_TYPE_F);
		
		flGame = GameUtils.fab(RobotManager.getRobot(), coin, room.getNum(), 1, room);
		
	}
	
	@PreDestroy
	public void preDestroy() {
		//Write Obj to File
		if(flGame == null)return;
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("flGame.obj"));
            oos.writeObject(flGame);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(oos);
        }
		
	}

	public static QhbGame backFlgame() {
		//Read Obj from File
        File file = new File("flGame.obj");
        if(!file.exists())return null;
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream(file));
            flGame = (QhbGame) ois.readObject();
            return flGame;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            IOUtils.closeQuietly(ois);
            try {
                FileUtils.forceDelete(file);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
	}
	
}
